home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 2
/
Atari Mega Archive CD - Volume 2.iso
/
minix
/
up1510b.tgz
/
up1510b
/
src
/
commands
/
ed.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-23
|
42KB
|
2,160 lines
/* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
/* This program used to be in many little pieces, with this makefile:
.SUFFIXES: .c .s
CFLAGS = -F
OBJS = append.s catsub.s ckglob.s deflt.s del.s docmd.s doglob.s\
doprnt.s doread.s dowrite.s ed.s egets.s find.s getfn.s getlst.s\
getnum.s getone.s getptr.s getrhs.s gettxt.s ins.s join.s maksub.s\
move.s optpat.s set.s setbuf.s subst.s getpat.s matchs.s amatch.s\
unmkpat.s omatch.s makepat.s bitmap.s dodash.s esc.s system.s
ed: $(OBJS)
cc -T. -i -o ed $(OBJS)
*/
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
/****************************/
/* tools.h */
/*
* #defines for non-printing ASCII characters
*/
#define NUL 0x00 /* ^@ */
#define EOS 0x00 /* end of string */
#define SOH 0x01 /* ^A */
#define STX 0x02 /* ^B */
#define ETX 0x03 /* ^C */
#define EOT 0x04 /* ^D */
#define ENQ 0x05 /* ^E */
#define ACK 0x06 /* ^F */
#define BEL 0x07 /* ^G */
#define BS 0x08 /* ^H */
#define HT 0x09 /* ^I */
#define LF 0x0a /* ^J */
#define NL '\n'
#define VT 0x0b /* ^K */
#define FF 0x0c /* ^L */
#define CR 0x0d /* ^M */
#define SO 0x0e /* ^N */
#define SI 0x0f /* ^O */
#define DLE 0x10 /* ^P */
#define DC1 0x11 /* ^Q */
#define DC2 0x12 /* ^R */
#define DC3 0x13 /* ^S */
#define DC4 0x14 /* ^T */
#define NAK 0x15 /* ^U */
#define SYN 0x16 /* ^V */
#define ETB 0x17 /* ^W */
#define CAN 0x18 /* ^X */
#define EM 0x19 /* ^Y */
#define SUB 0x1a /* ^Z */
#define ESC 0x1b /* ^[ */
#define FS 0x1c /* ^\ */
#define GS 0x1d /* ^] */
#define RS 0x1e /* ^^ */
#define US 0x1f /* ^_ */
#define SP 0x20 /* space */
#define DEL 0x7f /* DEL */
#define TRUE 1
#define FALSE 0
#define ERR -2
/* Definitions of meta-characters used in pattern matching
* routines. LITCHAR & NCCL are only used as token identifiers;
* all the others are also both token identifier and actual symbol
* used in the regular expression.
*/
#define BOL '^'
#define EOL '$'
#define ANY '.'
#define LITCHAR 'L'
#define ESCAPE '\\'
#define CCL '[' /* Character class: [...] */
#define CCLEND ']'
#define NEGATE '~'
#define NCCL '!' /* Negative character class [^...] */
#define CLOSURE '*'
#define OR_SYM '|'
#define DITTO '&'
#define OPEN '('
#define CLOSE ')'
/* Largest permitted size for an expanded character class. (i.e. the class
* [a-z] will expand into 26 symbols; [a-z0-9] will expand into 36.)
*/
#define CLS_SIZE 128
/*
* Tokens are used to hold pattern templates. (see makepat())
*/
typedef char BITMAP;
typedef struct token {
char tok;
char lchar;
BITMAP *bitmap;
struct token *next;
} TOKEN;
#define TOKSIZE sizeof (TOKEN)
/*
* An absolute maximun for strings.
*/
#define MAXSTR 132 /* Maximum numbers of characters in a line */
extern char *matchs();
extern char *amatch();
extern char *in_string();
extern TOKEN *getpat();
extern int esc();
extern char *dodash();
extern TOKEN *makepat();
extern int unmakepat();
extern int insert();
extern int delete();
extern int isalphanum();
extern char *stoupper();
extern int pr_tok();
extern int pr_line();
extern BITMAP *makebitmap();
void set_buf();
/* Macros */
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a<b)?a:b)
#define toupper(c) (c>='a'&&c<='z'?c-32:c)
/* ed.h */
#define FATAL (ERR-1)
struct line {
int l_stat; /* empty, mark */
struct line *l_prev;
struct line *l_next;
char l_buff[1];
};
typedef struct line LINE;
#define LINFREE 1 /* entry not in use */
#define LGLOB 2 /* line marked global */
#define MAXLINE 256 /* max number of chars per line */
#define MAXPAT 256 /* max number of chars per replacement
* pattern */
#define MAXFNAME 256 /* max file name size */
extern LINE line0;
extern int curln, lastln, line1, line2, nlines;
extern int nflg; /* print line number flag */
extern int lflg; /* print line in verbose mode */
extern char *inptr; /* tty input buffer */
extern char linbuf[], *linptr; /* current line */
extern int truncflg; /* truncate long line flag */
extern int eightbit; /* save eighth bit */
extern int nonascii; /* count of non-ascii chars read */
extern int nullchar; /* count of null chars read */
extern int truncated; /* count of lines truncated */
extern int fchanged; /* file changed */
#define nextln(l) ((l)+1 > lastln ? 0 : (l)+1)
#define prevln(l) ((l)-1 < 0 ? lastln : (l)-1)
extern char *getfn();
extern LINE *getptr();
extern char *gettxt();
extern char *maksub();
extern TOKEN *optpat();
extern char *catsub();
extern char *strcpy(), *strcat();
extern char *malloc();
/* amatch.c */
/* #include <stdio.h> */
/* #include "tools.h" */
/* Scans throught the pattern template looking for a match
* with lin. Each element of lin is compared with the template
* until either a mis-match is found or the end of the template
* is reached. In the former case a 0 is returned; in the latter,
* a pointer into lin (pointing to the character following the
* matched pattern) is returned.
*
* "lin" is a pointer to the line being searched.
* "pat" is a pointer to a template made by makepat().
* "boln" is a pointer into "lin" which points at the
* character at the beginning of the line.
*/
char *paropen[9], *parclose[9];
int between, parnum;
static char *match();
char *amatch(lin, pat, boln)
char *lin;
TOKEN *pat;
char *boln;
{
between = 0;
parnum = 0;
lin = match(lin, pat, boln);
if (between) return 0;
while (parnum < 9) {
paropen[parnum] = parclose[parnum] = "";
parnum++;
}
return lin;
}
static char *match(lin, pat, boln)
char *lin;
TOKEN *pat;
char *boln;
{
register char *bocl, *rval, *strstart;
if (pat == 0) return 0;
strstart = lin;
while (pat) {
if (pat->tok == CLOSURE && pat->next) {
/* Process a closure: first skip over the closure
* token to the object to be repeated. This object
* can be a character class. */
pat = pat->next;
/* Now match as many occurrences of the closure
* pattern as possible. */
bocl = lin;
while (*lin && omatch(&lin, pat, boln));
/* 'Lin' now points to the character that made made
* us fail. Now go on to process the rest of the
* string. A problem here is a character following
* the closure which could have been in the closure.
* For example, in the pattern "[a-z]*t" (which
* matches any lower-case word ending in a t), the
* final 't' will be sucked up in the while loop.
* So, if the match fails, we back up a notch and try
* to match the rest of the string again, repeating
* this process recursively until we get back to the
* beginning of the closure. The recursion goes, at
* most two levels deep. */
if (pat = pat->next) {
int savbtwn = between;
int savprnm = parnum;
while (bocl <= lin) {
if (rval = match(lin, pat, boln)) {
/* Success */
return(rval);
} else {
--lin;
between = savbtwn;
parnum = savprnm;
}
}
return(0); /* match failed */
}
} else if (pat->tok == OPEN) {
if (between || parnum >= 9) return 0;
paropen[parnum] = lin;
between = 1;
pat = pat->next;
} else if (pat->tok == CLOSE) {
if (!between) return 0;
parclose[parnum++] = lin;
between = 0;
pat = pat->next;
} else if (omatch(&lin, pat, boln)) {
pat = pat->next;
} else {
return(0);
}
}
/* Note that omatch() advances lin to point at the next character to
* be matched. Consequently, when we reach the end of the template,
* lin will be pointing at the character following the last character
* matched. The exceptions are templates containing only a BOLN or
* EOLN token. In these cases omatch doesn't advance.
*
* A philosophical point should be mentioned here. Is $ a position or a
* character? (i.e. does $ mean the EOL character itself or does it
* mean the character at the end of the line.) I decided here to
* make it mean the former, in order to make the behavior of match()
* consistent.